﻿namespace Wolfpack.Contrib.Checks.CpuThreshold
{
    using System;
    using System.Collections.Generic;
    using System.Management;
    using Wolfpack.Core;
    using Wolfpack.Core.Interfaces;
    using Wolfpack.Core.Interfaces.Entities;

    public class ThresholdAlarmConfig : PluginConfigBase
    {
        public string SampleNumber { get; set; }

        public string Threshold { get; set; }
    }

    public class ThresholdAlarm : IHealthCheckPlugin
    {
        public ThresholdAlarm(ThresholdAlarmConfig config)
        {
            this.MyConfig = config;
        }

        public int SampleCount { get; set; }

        public int SampleNumber { get; set; }

        public ThresholdAlarmConfig MyConfig { get; set; }

        public Status Status { get; set; }

        public PluginDescriptor Identity
        {
            get
            {
                return new PluginDescriptor
                {
                    Description = "Cpu Threshold Alarm",
                    Name = this.MyConfig.FriendlyId,

                    // The TypeId is important - it needs to be different for
                    // each health check as this allows us to positively identify
                    // every health check. Use the VS Tools/Create GUID tool to
                    // generate a new one.
                    TypeId = new Guid("6E68371D-9DC2-44d9-B57C-51487235583C")
                };
            }
        }

        public void Initialise()
        {
            this.SampleNumber = Int16.Parse(this.MyConfig.SampleNumber);
        }

        public void Execute()
        {
            try
            {
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(
                    "root\\CIMV2",
                    "SELECT * FROM Win32_PerfFormattedData_Counters_ProcessorInformation WHERE PercentProcessorTime >= "
                    + Int16.Parse(this.MyConfig.Threshold)
                    + " AND Name = '_Total'");

                if (searcher.Get().Count >= 1)
                {
                    this.SampleCount++;

                    if (this.SampleCount == this.SampleNumber)
                    {
                        this.Publish();
                        this.SampleCount--;
                    }
                }
                else
                {
                    this.SampleCount = 0;
                }
            }
            catch (Exception e)
            {
                Logger.Debug("{0}: An error occurred during Execute {1}", this.MyConfig.FriendlyId, e.Message);
                return;
            }



            Logger.Debug("{0}: Done checking cpu threshold.", this.MyConfig.FriendlyId);
        }

        public void Publish()
        {
            try
            {
                var result = new HealthCheckData
                {
                    Identity = this.Identity,
                    Result = false,
                    Info = String.Format("Cpu exceeded {0}%.", this.MyConfig.Threshold),
                    Tags = this.MyConfig.Threshold
                };

                result.Properties = new ResultProperties
                {
                    { 
                        "Threshold", this.MyConfig.Threshold 
                    }
                };

                Messenger.Publish(result);
            }
            catch (Exception ex)
            {
                Logger.Error("Error during publish: {0}", ex.Message);
            }
        }

        /////// <summary>
        /////// To be used if we decide to calculate by process.  
        /////// </summary>
        ////public void CalcProcess()
        ////{
        ////    try
        ////    {
        ////        ManagementObjectSearcher searcher =
        ////                   new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PerfFormattedData_PerfProc_Process");

        ////        foreach (ManagementObject queryObj in searcher.Get())
        ////        {
        ////            // this.ProcessPercent.Add(queryObj["Name"].ToString(), float.Parse(queryObj["PercentProcessorTime"].ToString()));
        ////        }
        ////    }
        ////    catch (Exception e)
        ////    {
        ////        Logger.Error(e.ToString());
        ////    }
        ////}
    }
}
